/*
 * @ProjectName: 编程学习
 * @Copyright:   2019 HangZhou Yi Dev, Ltd. All Right Reserved.
 * @address:     https://yiyuery.github.io/
 * @date:        2019/5/20 20:57
 * @email:       xiazhaoyang@live.com
 * @description: 本内容仅限于编程技术学习使用，转发请注明出处.
 */
package com.example.swagger.common.component;

import com.example.swagger.api.AutoRegister;
import com.example.swagger.api.ITransformPlugin;
import com.example.swagger.api.PropNameSpace;
import com.example.swagger.common.base.AbstractOfficeTransformPlugin;
import com.example.swagger.common.base.AbstractSwaggerTransformPlugin;
import com.example.swagger.common.configuration.ApplicationYamlLoader;
import com.example.swagger.common.configuration.OfficeTransformConfig;
import com.example.swagger.common.context.AppBeanContext;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.List;

/**
 * <p>
 * 启动初始化类
 * </p>
 *
 * @author Yi
 * @version v1.0.0
 * @date 2019-06-07 05:33
 * @modificationHistory=========================逻辑或功能性重大变更记录
 * @modify By: {修改人} 2019-06-07
 * @modify reason: {方法名}:{原因}
 * ...
 */
@Slf4j
@Setter
public class AppStarterInitial {

    {
        log.info("SWAGGER-API-TRANSFORM STARTING...");
        beforeStart();
        log.info("SWAGGER-API-TRANSFORM COMPLETED ALL INITIAL TASK...");
    }

    /**
     * 加载配置
     */
    public void loadProps(String loader) {
        if (StringUtils.isNotBlank(loader)) {
            ApplicationYamlLoader.reload(loader);
        } else {
            ApplicationYamlLoader.loadDefaultProps();
        }
    }

    /**
     * 子类覆盖加载函数
     */
    public void loadProps() {
        ApplicationYamlLoader.loadDefaultProps();
    }

    private void beforeStart() {
        try {
            loadProps();
            ClasspathPackageScanner scan = new ClasspathPackageScanner("com.example.swagger");
            List<String> classNames = scan.getFullyQualifiedClassNameList();
            for (String clazz : classNames) {
                Class<?> c = Thread.currentThread().getContextClassLoader().loadClass(clazz);
                if (c.getAnnotations().length > 0) {
                    //获取自动注入对象
                    if (c.getAnnotationsByType(AutoRegister.class).length > 0) {
                        Object bean = c.newInstance();
                        //遍历属性中所有Field
                        String prefixKey = "";
                        if (c.getAnnotationsByType(PropNameSpace.class).length > 0) {
                            PropNameSpace[] annotationsByType = c.getAnnotationsByType(PropNameSpace.class);
                            prefixKey = annotationsByType[0].prefix();
                        }
                        Field[] declaredFields = c.getDeclaredFields();

                        for (Field field : declaredFields) {
                            field.setAccessible(Boolean.TRUE);
                            String filedKey = field.getAnnotationsByType(JsonProperty.class).length > 0 ? field.getAnnotationsByType(JsonProperty.class)[0].value() : field.getName();
                            String propKey = prefixKey + "." + filedKey;
                            field.set(bean, ApplicationYamlLoader.getPropsByKey(propKey, field.getType()));
                        }
                        String beanName = c.getAnnotationsByType(AutoRegister.class)[0].name();
                        AppBeanContext.getInstance().registerBean(
                                StringUtils.isNotBlank(beanName) ? beanName : StringUtils.lowerCase(c.getSimpleName()).substring(0, 1) + c.getSimpleName().substring(1),
                                bean);
                    }
                }
            }
        } catch (Throwable e) {
            log.error("init error", e);
        }
    }

    /**
     * 根据选择的插件生成 ASCIIDOC\MARKDOWN\CONFLUENCE 文件
     *
     * @param plugin
     */
    protected void run(ITransformPlugin plugin) {

        if (plugin instanceof AbstractSwaggerTransformPlugin) {
            ((AbstractSwaggerTransformPlugin) plugin).gen();
        }

        if (plugin instanceof AbstractOfficeTransformPlugin) {
            ((AbstractOfficeTransformPlugin) plugin).gen();
        }
    }
}
